/*
 * \file CplexStabSolver.h
 * \brief Clase CplexStabSolver, implementación de StabSolver para Cplex
 *
 *  Created on: Jan 24, 2014
 *      Author: ik
 */

#ifndef CPLEXSTABSOLVER_H_
#define CPLEXSTABSOLVER_H_

#include <Grafo.h>
#include <CplexDesigualdades.h>
#include <StabBranching.h>
#include <StabSolver.h>
#include <Separator.h>
#include <Solucion.h>

/*!
 * \class CplexStabSolver
 * \brief Implementación de StabSolver para Cplex
 */
class CplexStabSolver : public StabSolver
{
	Grafo& _grafo;

public:
	CplexStabSolver(Grafo &grafo) : _grafo(grafo) {};
	~CplexStabSolver() {};
	/*!
	 * \fn DoubleValueArray* solve(SeparatorParameters& parameters)
	 * \brief  Ejecuta el algoritmo entero para cplex
	 *
	 * \param parameters Para controlar ejecución
	 */
	DoubleValueArray* solve(SeparatorParameters& parameters);
	/*!
	 * \fn DoubleValueArray* solveLinearRelaxation()
	 * \brief Ejecuta la relajacion lineal.
	 */
	DoubleValueArray* solveLinearRelaxation();
};

class CplexSolucion : public Solucion {
protected:
	IloCplex::ControlCallbackI *	_model;
	IloNumVarArray& 				_x;

	CplexSolucion(IloCplex::ControlCallbackI * model, IloNumVarArray& x, int n);

public:
	CplexSolucion(IloCplex::ControlCallbackI * model, IloNumVarArray& x);
	~CplexSolucion() {};

	virtual const double operator [](int i) const;
	virtual double operator [](int i);
	virtual void setValue(const int i, const double valor);
	virtual double value();
	virtual void print() const;
};

class CplexSeparator : public Separator
{
protected:
	IloNumVarArray&		_x;

	Desigualdad * newDesigualdad() { return new CplexDesigualdad(_x); };
	Desigualdad * newDesigualdad(const Desigualdad& otra) { return new CplexDesigualdad(((CplexDesigualdad&) otra)); };

public:
	CplexSeparator(Grafo &grafo, IloNumVarArray& x, SeparatorParameters &parametros) : Separator(grafo, parametros), _x(x) {};
	~CplexSeparator() {};
};

class CplexBranching : public StabStabBranching
{
protected:
	IloNumVarArray&	_x;
	CplexBranching(Grafo &grafo, IloNumVarArray& x, const VertexSet& subgrafo, ReservaClique * reserva) : StabStabBranching(grafo, subgrafo, reserva), _x(x) {};
	virtual Desigualdad * newDesigualdad() { return new CplexDesigualdad(_x); };
	virtual Desigualdad * newDesigualdad(const Desigualdad& otra) { return new CplexDesigualdad(((CplexDesigualdad&) otra)); };

public:
	CplexBranching(Grafo &grafo, IloNumVarArray& x, ReservaClique * reserva=NULL) : StabStabBranching(grafo, reserva), _x(x) {};
	virtual ~CplexBranching() {};
};

#endif /* CPLEXSTABSOLVER_H_ */
